/*
 * X1000 cpm definitions
 *
 * Copyright (c) 2013 Ingenic Semiconductor Co.,Ltd
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifndef __X1000_H__
#define __X1000_H__

#define	OST_BASE				0xb2000000

/* AHB0 BUS Devices */
#define DDRC_BASE				0xb34f0000

/* AHB2 BUS Devices */
#define SFC_BASE				0xb3440000
#define MSC0_BASE				0xb3450000
#define MSC1_BASE				0xb3460000
#define ETHC_BASE				0xb34b0000
#define EFUSE_BASE				0xb3540000

/* APB BUS Devices */
#define	CPM_BASE				0xb0000000
#define	GPIO_BASE				0xb0010000
#define	UART0_BASE				0xb0030000
#define	UART1_BASE				0xb0031000
#define	UART2_BASE				0xb0032000
#define	WDT_BASE				0xb0002000

/*************************************************************************
 * CPM (Clock reset and Power control Management)
 *************************************************************************/
#define CPM_CPCCR				0x00 /* Clock control register		*/
#define CPM_CPCSR				0xd4 /* Clock Status register		*/
#define CPM_CPAPCR				0x10 /* APLL control Register		*/
#define CPM_CPMPCR				0x14 /* MPLL control Register		*/
#define CPM_DDRCDR				0x2c /* DDR clock divider register	*/
#define CPM_MACCDR				0x54 /* MAC clock divider register	*/
#define CPM_MSC0CDR				0x68 /* MSC0 clock divider register	*/
#define CPM_MSC1CDR				0xa4 /* MSC1 clock divider register	*/
#define CPM_SSICDR				0x74 /* SSI clock divider register	*/
#define CPM_DRCG				0xd0
#define CPM_MPHYC				(CPM_BASE+0xe8)

#define CPM_LCR					(CPM_BASE+0x04)
#define CPM_CLKGR				0x20 /* Clock Gate Register */
#define CPM_OPCR				(CPM_BASE+0x24) /* Oscillator and Power Control Register */

/* DDR clock divider register */
#define CPM_DDRCDR_DCS_BIT		30
#define CPM_DDRCDR_DCS_MASK		(3 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_DCS_STOP		(0x0 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_DCS_SCLKA	(0x1 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_DCS_MPLL		(0x2 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_CE			(1 << 29)
#define CPM_DDRCDR_DDR_BUSY		(1 << 28)
#define CPM_DDRCDR_DDR_STOP		(1 << 27)
#define CPM_DDRCDR_GATE_EN		(1 << 26)
#define CPM_DDRCDR_DDRDIV_BIT	0
#define CPM_DDRCDR_DDRDIV_MASK	(0xf << CPM_DDRCDR_DDRDIV_BIT)

/* MAC clock divider register */
#define CPM_MACCDR_MACPCS_BIT	31
#define CPM_MACCDR_MACPCS_MASK	(1 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_MACPCS_SCLKA	(0x0 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_MACPCS_MPLL	(0x1 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_CE			(1 << 29)
#define CPM_MACCDR_MAC_BUSY		(1 << 28)
#define CPM_MACCDR_MAC_STOP		(1 << 27)
#define CPM_MACCDR_MACDIV_BIT	0
#define CPM_MACCDR_MACDIV_MASK	(0xff << CPM_MACCDR_MACDIV_BIT)

/* MSC clock divider register */
#define CPM_MSCCDR_MPCS_BIT		31
#define CPM_MSCCDR_MPCS_MASK	(1 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_MPCS_SCLKA	(0x0 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_MPCS_MPLL	(0x1 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_CE			(1 << 29)
#define CPM_MSCCDR_MSC_BUSY		(1 << 28)
#define CPM_MSCCDR_MSC_STOP		(1 << 27)
#define CPM_MSCCDR_MSC_CLK0_SEL	(1 << 15)
#define CPM_MSCCDR_MSCDIV_BIT	0
#define CPM_MSCCDR_MSCDIV_MASK	(0xff << CPM_MSCCDR_MSCDIV_BIT)

/* SSI clock divider register */
#define CPM_SSICDR_SPCS_BIT	31
#define CPM_SSICDR_SPCS_MASK	(1 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SPCS_SCLKA	(0x0 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SPCS_MPLL	(0x1 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SCS_BIT		30
#define CPM_SSICDR_SCS_MASK		(1 << CPM_SSICDR_SCS_BIT)
#define CPM_SSICDR_SCS_EXCLK	(0x0 << CPM_SSICDR_SCS_BIT)
#define CPM_SSICDR_SCS_PLL_DIV2	(0x1 << CPM_SSICDR_SCS_BIT)
#define CPM_SSICDR_CE			(1 << 29)
#define CPM_SSICDR_SSI_BUSY		(1 << 28)
#define CPM_SSICDR_SSI_STOP		(1 << 27)
#define CPM_SSICDR_SSIDIV_BIT	0
#define CPM_SSICDR_SSIDIV_MASK	(0xff << CPM_SSICDR_SSIDIV_BIT)

/* Low Power Control Register */
#define CPM_LCR_PST_BIT 		8
#define CPM_LCR_PST_MASK 		(0xfff << CPM_LCR_PST_BIT)
#define CPM_LCR_LPM_BIT			0
#define CPM_LCR_LPM_MASK		(0x3 << CPM_LCR_LPM_BIT)
#define CPM_LCR_LPM_IDLE		(0x0 << CPM_LCR_LPM_BIT)
#define CPM_LCR_LPM_SLEEP		(0x1 << CPM_LCR_LPM_BIT)

/* Clock Gate Register */
#define CPM_CLKGR_DDR			(1 << 31)
#define CPM_CLKGR_CPU			(1 << 30)
#define CPM_CLKGR_AHB0			(1 << 29)
#define CPM_CLKGR_APB0			(1 << 28)
#define CPM_CLKGR_RTC			(1 << 27)
#define CPM_CLKGR_PCM			(1 << 26)
#define CPM_CLKGR_MAC			(1 << 25)
#define CPM_CLKGR_AES			(1 << 24)
#define CPM_CLKGR_LCD			(1 << 23)
#define CPM_CLKGR_CIM			(1 << 22)
#define CPM_CLKGR_PDMA			(1 << 21)
#define CPM_CLKGR_OST			(1 << 20)
#define CPM_CLKGR_SSI			(1 << 19)
#define CPM_CLKGR_TCU			(1 << 18)
#define CPM_CLKGR_DMIC			(1 << 17)
#define CPM_CLKGR_UART2			(1 << 16)
#define CPM_CLKGR_UART1			(1 << 15)
#define CPM_CLKGR_UART0			(1 << 14)
#define CPM_CLKGR_SADC			(1 << 13)
#define CPM_CLKGR_JPEG			(1 << 12)
#define CPM_CLKGR_AIC			(1 << 11)
#define CPM_CLKGR_I2C3			(1 << 10)
#define CPM_CLKGR_I2C2			(1 << 9)
#define CPM_CLKGR_I2C1			(1 << 8)
#define CPM_CLKGR_I2C0			(1 << 7)
#define CPM_CLKGR_SCC			(1 << 6)
#define CPM_CLKGR_MSC1			(1 << 5)
#define CPM_CLKGR_MSC0			(1 << 4)
#define CPM_CLKGR_OTG			(1 << 3)
#define CPM_CLKGR_SFC			(1 << 2)
#define CPM_CLKGR_EFUSE			(1 << 1)
#define CPM_CLKGR_NEMC			(1 << 0)

/* Oscillator and Power Control Register */
#define CPM_OPCR_IDLE_DIS		(1 << 31)
#define CPM_OPCR_MASK_INT		(1 << 30)
#define CPM_OPCR_GATE_SCLKA_BUS	(1 << 28)
#define CPM_OPCR_L2C_PD			(1 << 25)
#define CPM_OPCR_REQ_MODE		(1 << 24)
#define CPM_OPCR_GATE_USBPHYCLK	(1 << 23)
#define CPM_OPCR_DISABLE_MUX	(1 << 22)
#define CPM_OPCR_O1ST_BIT		8
#define CPM_OPCR_O1ST_MASK		(0xff << CPM_OPCR_O1ST_BIT)
#define CPM_OPCR_SPENDN0		(1 << 7)
#define CPM_OPCR_SPENDN1		(1 << 6)
#define CPM_OPCR_CPU_MODE		(1 << 5)
#define CPM_OPCR_O1SE			(1 << 4) /* */
#define CPM_OPCR_PD				(1 << 3)
#define CPM_OPCR_ERCS			(1 << 2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
#define CPM_OPCR_BUS_MODE		(1 << 1)

//n = 0,1,2,3
#define GPIO_PXPIN(n)			(0x00 + (n) * 0x100) /* PIN Level Register */
#define GPIO_PXINT(n)			(0x10 + (n) * 0x100) /* Port Interrupt Register */
#define GPIO_PXINTS(n)			(0x14 + (n) * 0x100) /* Port Interrupt Set Register */
#define GPIO_PXINTC(n)			(0x18 + (n) * 0x100) /* Port Interrupt Clear Register */
#define GPIO_PXMASK(n)			(0x20 + (n) * 0x100) /* Port Interrupt Mask Register */
#define GPIO_PXMASKS(n)			(0x24 + (n) * 0x100) /* Port Interrupt Mask Set Reg */
#define GPIO_PXMASKC(n)			(0x28 + (n) * 0x100) /* Port Interrupt Mask Clear Reg */
#define GPIO_PXPAT1(n)			(0x30 + (n) * 0x100) /* Port Pattern 1 Register */
#define GPIO_PXPAT1S(n)			(0x34 + (n) * 0x100) /* Port Pattern 1 Set Reg. */
#define GPIO_PXPAT1C(n)			(0x38 + (n) * 0x100) /* Port Pattern 1 Clear Reg. */
#define GPIO_PXPAT0(n)			(0x40 + (n) * 0x100) /* Port Pattern 0 Register */
#define GPIO_PXPAT0S(n)			(0x44 + (n) * 0x100) /* Port Pattern 0 Set Register */
#define GPIO_PXPAT0C(n)			(0x48 + (n) * 0x100) /* Port Pattern 0 Clear Register */
#define GPIO_PXFLG(n)			(0x50 + (n) * 0x100) /* Port Flag Register */
#define GPIO_PXFLGC(n)			(0x58 + (n) * 0x100) /* Port Flag clear Register */
#define GPIO_PXPEN(n)			(0x70 + (n) * 0x100) /* Port Pull Disable Register */
#define GPIO_PXPENS(n)			(0x74 + (n) * 0x100) /* Port Pull Disable Set Register */
#define GPIO_PXPENC(n)			(0x78 + (n) * 0x100) /* Port Pull Disable Clear Register */

#define GPIO_PA(n) 				(0*32 + n)
#define GPIO_PB(n) 				(1*32 + n)
#define GPIO_PC(n) 				(2*32 + n)
#define GPIO_PD(n) 				(3*32 + n)

/**
 * Basic configuration(SOC, Cache, UART, DDR).
 */
#define CONFIG_SYS_APLL_FREQ		1200000000	/*If APLL not use mast be set 0*/
#define CONFIG_SYS_APLL_MNOD		((1 << 31) | (49 << 24) | (0 << 18) | (0 << 16))
#define CONFIG_SYS_MPLL_FREQ		600000000	/*If MPLL not use mast be set 0*/
#define CONFIG_SYS_MPLL_MNOD		((1 << 31) | (24 << 24) | (0 << 18) | (0 << 16))

#define CONFIG_SYS_CPU_FREQ			CONFIG_SYS_APLL_FREQ
#define CONFIG_SYS_MEM_FREQ			(CONFIG_SYS_MPLL_FREQ / 3)

#define CONFIG_MDDR_JSD12164PAI_KGD	/*DDR 64M param file*/

#define CONFIG_SPL_CORE_VOLTAGE			1350
#define CONFIG_SPL_CORE_VOLTAGE_RATIO	1/2

#ifndef __ASSEMBLY__

#include <asm/io.h>

static inline int gpio_get_value(unsigned gpio)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
	unsigned port = gpio / 32;
	unsigned pin = gpio % 32;

	return !!(readl(gpio_regs + GPIO_PXPIN(port)) & (1 << pin));
}

static inline void gpio_port_set(int port, int pin, int value)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;

	if (value)
		writel(1 << pin, gpio_regs + GPIO_PXPAT0S(port));
	else
		writel(1 << pin, gpio_regs + GPIO_PXPAT0C(port));
}

static inline void gpio_port_direction_input(int port, int pin)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;

	writel(1 << pin, gpio_regs + GPIO_PXINTC(port));
	writel(1 << pin, gpio_regs + GPIO_PXMASKS(port));
	writel(1 << pin, gpio_regs + GPIO_PXPAT1S(port));
}

static inline void gpio_port_direction_output(int port, int pin, int value)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;

	writel(1 << pin, gpio_regs + GPIO_PXINTC(port));
	writel(1 << pin, gpio_regs + GPIO_PXMASKS(port));
	writel(1 << pin, gpio_regs + GPIO_PXPAT1C(port));

	gpio_port_set(port, pin, value);
}

static inline void gpio_direction_input(int gpio)
{
	int port = gpio / 32;
	int pin = gpio % 32;

	gpio_port_direction_input(port, pin);
}

static inline void gpio_direction_output(int gpio, int value)
{
	int port = gpio / 32;
	int pin = gpio % 32;

	gpio_port_direction_output(port, pin, value);
}

#endif /* __ASSEMBLY__ */

#endif /* __X1000_H__ */
